package com.qianqian.service.service;

import com.qianqian.service.exception.BusinessError;
import com.qianqian.service.exception.BusinessException;
import com.qianqian.service.mapper.CapitalAccountMapper;
import com.qianqian.service.mapper.GameRecordMapper;
import com.qianqian.service.mapper.GameResultMapper;
import com.qianqian.service.mapper.GameSceneMapper;
import com.qianqian.service.model.*;
import com.qianqian.service.utils.GameRuleTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;

@Service
public class ZhuanPanService {

    @Autowired
    GameResultMapper gameResultMapper;

    @Autowired
    GameRecordMapper gameRecordMapper;

    @Autowired
    CapitalAccountMapper capitalAccountMapper;

    @Autowired
    GameSceneMapper gameSceneMapper;

    private static final int SCENE_MAX_COUNT = 90;

    private static final double JI_FEN = 0.1;


    @Transactional
    public GameResult newGameNumber(String userId){
        GameResult gameResult = new GameResult();
        gameResult.setGameNumber(Integer.parseInt(String.valueOf(System.currentTimeMillis() / 1000)));
        gameResult.setGameTypeCode(GameType.GAME_TYPE_ZHUANPAN);
        gameResult.setCreateDate(new Date());
        gameResult.setCreateUserId(userId);
        gameResultMapper.insertSelective(gameResult);
        GameScene gameScene = gameSceneMapper.selectNewScene();
        if(gameScene.getGameCount()+1==SCENE_MAX_COUNT){
            gameScene.setEndGameNumber(gameResult.getGameNumber());
            GameScene newGameScene = new GameScene();
            newGameScene.setStartGameNumber(gameResult.getGameNumber());
            newGameScene.setCreateDate(new Date());
            newGameScene.setCreateUserId(userId);
            newGameScene.setGameCount(0);
            if(gameSceneMapper.insertSelective(newGameScene)<1){
                throw new BusinessException(BusinessError.BUSINESS_ERROR);
            }
        }
        gameScene.setGameCount(gameScene.getGameCount()+1);
        if(gameSceneMapper.updateByPrimaryKeySelective(gameScene)<1){
            throw new BusinessException(BusinessError.BUSINESS_ERROR);
        }
        return gameResult;
    }

    public GameResult selectNewGameNumber(){
        return gameResultMapper.selectNewGameNumber();
    }

    public GameResult getGameResul(int gameNumber){
        GameResult gameResult = gameResultMapper.selectByGameNumber(gameNumber);
        if(gameResult.getResult()==null){
            try {
                Thread.sleep(500l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            return gameResult;
        }
        return getGameResul(gameNumber);
    }

    @Transactional
    public void xiaZhu(List<GameRecord> gameRecords,LoginUser loginUser){
        double chip = 0.0;
        int gameNumber = 0;
        for (GameRecord gameRecord : gameRecords) {
            gameNumber = gameRecord.getGameNumber();
            gameRecord.setCreateDate(new Date());
            gameRecord.setUserId(loginUser.getUserId());
            gameRecordMapper.insertSelective(gameRecord);
            chip = chip-gameRecord.getChip();
        }
        CapitalAccount capitalAccount = new CapitalAccount();
        capitalAccount.setUserId(loginUser.getUserId());
        capitalAccount.setYue(chip);
        if(selectGameRecordsByGameNumber(gameNumber,loginUser.getUserId()).size()==gameRecords.size()){
            capitalAccount.setJifenYue(this.JI_FEN);
        }
        if(capitalAccountMapper.updateResultChipByUserId(capitalAccount)<1){
            throw new BusinessException(BusinessError.BUSINESS_ERROR);
        }
    }

    @Transactional
    public int setResult(GameResult gameResult,int gameNumber,LoginUser loginUser,Boolean isStop){
        GameResultExample gameResultExample = new GameResultExample();
        GameResultExample.Criteria criteria =  gameResultExample.createCriteria();
        criteria.andGameNumberEqualTo(gameNumber);
        criteria.andResultIsNull();
        gameResultExample.or(criteria);
        if(gameResultMapper.updateByExampleSelective(gameResult,gameResultExample) < 1){
            throw new BusinessException(BusinessError.BUSINESS_ERROR);
        }
        //结算
        List<GameRecord> gameRecords = selectGameRecordsByGameNumber(gameNumber);
        for (GameRecord gameRecord : gameRecords) {
            double chip = gameRecord.getChip();
            double resultChip = 0;
            boolean result = GameRuleTools.getZhuanPanXiaZhuResult(Integer.parseInt(gameResult.getResult()),gameRecord.getGameRuleCode());
            if(result){
                resultChip = chip * GameRuleTools.getOdds(gameRecord.getGameRuleCode()) + chip;
            }else{
                resultChip = 0;
            }
            gameRecord.setResultChip(resultChip);
            gameRecord.setUpdateDate(new Date());
        }
        setResultChip(gameRecords);
        //是否开新局
        if(!isStop) {//开新局
            GameResult newGameNumber = newGameNumber(loginUser.getUserId());
            return newGameNumber.getGameNumber();
        }else{//暂停游戏
            GameScene gameScene = gameSceneMapper.selectNewScene();
            gameScene.setEndGameNumber(gameNumber);
            gameScene.setGameCount(gameScene.getGameCount()+1);
            if(gameSceneMapper.updateByPrimaryKeySelective(gameScene)<1){
                throw new BusinessException(BusinessError.BUSINESS_ERROR);
            }
            GameScene newGameScene = new GameScene();
            newGameScene.setStartGameNumber(gameNumber);
            newGameScene.setCreateDate(new Date());
            newGameScene.setCreateUserId(loginUser.getUserId());
            newGameScene.setGameCount(0);
            if(gameSceneMapper.insertSelective(newGameScene)<1){
                throw new BusinessException(BusinessError.BUSINESS_ERROR);
            }
        }
        return 0;
    }


    public List<GameRecord> selectGameRecordsByGameNumber(int gameNumber){
        GameRecordExample gameRecordExample = new GameRecordExample();
        GameRecordExample.Criteria criteria = gameRecordExample.createCriteria();
        criteria.andGameNumberEqualTo(gameNumber);
        gameRecordExample.or(criteria);
        return gameRecordMapper.selectByExample(gameRecordExample);
    }

    public List<GameRecord> selectGameRecordsByGameNumber(int gameNumber,String userId){
        GameRecordExample gameRecordExample = new GameRecordExample();
        GameRecordExample.Criteria criteria = gameRecordExample.createCriteria();
        criteria.andGameNumberEqualTo(gameNumber);
        criteria.andUserIdEqualTo(userId);
        gameRecordExample.or(criteria);
        return gameRecordMapper.selectByExample(gameRecordExample);
    }

    public List<GameResult> selectNewSceneGameResults(){
        return gameResultMapper.selectNewSceneGameResults();
    }

    @Transactional
    public void setResultChip(List<GameRecord> gameRecords){
        for (GameRecord gameRecord : gameRecords ) {
            CapitalAccount capitalAccount = new CapitalAccount();
            capitalAccount.setUserId(gameRecord.getUserId());
            capitalAccount.setYue(gameRecord.getResultChip());
            if(capitalAccountMapper.updateResultChipByUserId(capitalAccount)<1){
                throw new BusinessException(BusinessError.BUSINESS_ERROR);
            }
            gameRecord.setUpdateDate(new Date());
            gameRecord.setUpdateUserId(gameRecord.getUserId());
            gameRecord.setAccountYue(gameRecord.getResultChip());
            if(gameRecordMapper.updateByPrimaryKeySelective(gameRecord)<1){
                throw new BusinessException(BusinessError.BUSINESS_ERROR);
            }
        }
    }

    public boolean isEndScene(int gameNumber){
        return gameSceneMapper.selectByEndGameNumber(gameNumber) != null;
    }

    public void automaticGame(LoginUser loginUser,int gameNumber,String result,Boolean isStop) throws InterruptedException {
        GameResult gameResult = new GameResult();
        gameResult.setResult(result);
        gameResult.setResultDate(new Date());
        gameResult.setUpdateDate(new Date());
        gameResult.setUpdateUserId(loginUser.getUserId());
        int newGameNumber =  setResult(gameResult,gameNumber,loginUser,isStop);
        Thread.sleep(90000);
        int num = (int) (Math.random() * 4 + 1);
        automaticGame(loginUser,newGameNumber,String.valueOf(num),false);
    }
}
